/*
 *               ____
 *              /\   \
 *             ___\   \___
 *            /\          \
 *            \ \___    ___\
 *        ____ \/__/\   \__/
 *       /\   \    \ \___\    klof  |  innovative web technology
 *      ___\   \___ \/___/
 *     /\          \          klib3/xml.js
 *     \ \___    ___\         HTML Element animation
 *      \/__/\   \__/
 *          \ \___\           Copyright 2003-2006, klof
 *           \/___/           http://www.klof.net/k.lib3/
 *
 *  Based on original code by Netscape
 *  http://devedge.netscape.com/viewsource/2003/inner-browsing/
 *
 */


/* Create the master klib3 object if she doesn't exist */
if ( typeof klib3 != "object" )
	klib3 = new ( function(){ this._child = 0 } )();



klib3.xml = function( bSync )
{
	this._version = "1.0.0";
	this._sync    = typeof bSync == "boolean" ? bSync : false;
	this.init();
};
klib3.xml.prototype.request = function( sSource )
{
	this._xml.open( "GET", sSource, this._sync );
	this._xml.send( null );
}
klib3.xml.prototype.submit = function( sURL, sDocument )
{
	this._xml.open( "POST", sURL, this._sync );
	this._xml.send( sDocument );
}
klib3.xml.prototype.init = function()
{
	try
	{
		this._xml = new ActiveXObject( "Microsoft.XMLHTTP" );
		this.load = function( sSource )
		{
			this.request( sSource );
			return this._xml.responseXML;
		}
		this.send = function( sSource, sDocument )
		{
			this.submit( sSource, sDocument );
			return this._xml.responseXML;
		}
		this.loadString = function( sSource )
		{
			this.request( sSource );
			return this._xml.responseText;
		}
		this.sendString = function( sSource, sDocument )
		{
			this.submit( sSource, sDocument );
			return this._xml.responseText;
		}
	}
	catch( exception )
	{
		try
		{
			this._xml = new XMLHttpRequest();
			this.load = function( sSource )
			{
				this.request( sSource );
				if ( this._xml.responseXML )
					return this._xml.responseXML;
				return null;
			}
			this.send = function( sSource, sDocument )
			{
				this.submit( sSource, sDocument );
				if ( this._xml.responseXML )
					return this._xml.responseXML;
				return null;
			}
			this.loadString = function( sSource )
			{
				this.request( sSource );
				if ( this._xml.responseXML )
					return ( new XMLSerializer() ).serializeToString( this._xml.responseXML );
				return null;
			}
			this.sendString = function( sSource, sDocument )
			{
				this.submit( sSource, sDocument );
				if ( this._xml.responseXML )
					return ( new XMLSerializer() ).serializeToString( this._xml.responseXML );
				return null;
			}
		}
		catch( exception )
		{
			return false;
		}
	}
	return true;
}

/*
 *  Function : getHTMLfromXML
 *  Purpose  : retrieve a block of HTML DOM node from an XML DOM object
 *  Synopsis : domnode convertToHTML( xmlnode oXML [, string nodename ] );
 *  Note     : if string nodename is not specified, it will retrieve a HTML node from wherever 
 *             node that has an xmlns attribute set. If a xmlns attribute has been set and 
 *             string nodename is provided it will return thr HTML DOM node from whoever comes first
 */
klib3.xml.prototype.convertToHTML = function( oXML )
{
	var oNode = null;
	var oDOM  = null;

	alert( oXML.nodeName + " :: " + oXML.nodeType );
	if ( oXML.nodeType == 1 || oXML.nodeType == 9 ) // XML node OR XML declaration
	{
		var nOffset = oXML.nodeName.indexOf( ":" ) + 1;
		if ( oXML.nodeType == 1 && // are we handling a non-declaration non-text node?
			( nOffset > 0 || ( oXML.getAttribute( "xmlns" ) ) || // do we have a namespace?
				(
					arguments.length > 1 &&  // do we have additional arguments?
					( 
						( typeof arguments[ 1 ] == "boolean" && arguments[ 1 ] ) || // did we explicitly order to add this node?
						( typeof arguments[ 1 ] == "string" && arguments[ 1 ].toLowerCase() == oXML.nodeName.toLowerCase() ) // did we request to add this node because it's nodename matches out input?
					) 
				) 
			) 
		)
		{
			var sNodeName = nOffset > 0 ? oXML.nodeName.substr( nOffset, oXML.nodeName.length - nOffset ) : oXML.nodeName;
			oDOM  = document.createElement( sNodeName );
			for ( var i = 0; i < oXML.attributes.length; ++i )
			{
				if ( oXML.attributes[ i ].name == "class" )
					oDOM.className = oXML.attributes[ i ].value;
				else if ( oXML.attributes[ i ].name != "xmlns" )
					oDOM.setAttribute( oXML.attributes[ i ].name, oXML.attributes[ i ].value );
			}
			for ( var i = 0; i < oXML.childNodes.length; ++i )
				if ( ( name = oXML.childNodes[ i ].nodeName ) != null )
					if ( typeof ( oNode = arguments.callee( oXML.childNodes[ i ], true ) ) == "object" )
						oDOM.appendChild( oNode );
		}
		else // XML Declaration OR no namespace
		{
			for ( var i = 0; i < oXML.childNodes.length; ++i )
				if ( oXML.childNodes[ i ].nodeType == 1 )
					oDOM = arguments.callee( oXML.childNodes[ i ], arguments[ 1 ] );
		}
	}
	else if ( oXML.nodeType == 3 || oXML.nodeType == 4 ) // XML TextNode or XML CDATA Node
	{
		oDOM = document.createTextNode( oXML.nodeValue );
	}
	else if ( oXML.nodeType == 8 ) // XML Comment
	{
		oDOM = document.createComment( oXML.nodeValue );
	}
	return oDOM;
};

/*
 *  Function : xmlStructure
 *  Purpose  : Construct a tree containing arrays and objects which hold the XML data in a nice
 *             and orderly fashion
 *  Synopsis : array xmlStructure( object XML );
 */
klib3.xml.prototype.structure = function( oXML )
{
	var aTMP = new Array();
	var name = null;
	var nIndex;
	for ( var i = 0; i < oXML.childNodes.length; ++i )
		if ( ( name = oXML.childNodes[ i ].nodeName ) != null )
			if ( oXML.childNodes[ i ].nodeType == 1 )
			{
				aTMP[ name ] = aTMP[ nIndex ] = { name:name, value:( oXML.childNodes[ i ].firstChild ? ( ( value = oXML.childNodes[ i ].firstChild.nodeValue ) != null ? value : null ) : null ), attribute:oXML.childNodes[ i ].attributes };
				if ( oXML.childNodes[ i ].childNodes.length > 0 )
					aTMP[ name ].child = arguments.callee( oXML.childNodes[ i ] );
			}
	return aTMP;
}
